package socialnetworks;

import grafi.*;

import java.io.*;
import java.util.*;

import com.google.gdata.util.*;

public class GrafoYouTube extends GrafoLista<Arco> 
{	protected YouTubeDataExtractor extr=new YouTubeDataExtractor();
	protected HashMap<Integer,String> mappaNodiId=new HashMap<Integer,String>();
	
	public GrafoYouTube(int n, List<String> seeds) throws ServiceException, IOException //seeds sono id video
	{	super(n);
		popolaGrafo(seeds);
	}
	/* Costruttore aggiunto dal gruppo Visualizzazione per testing*/
	public GrafoYouTube(int n, List<String> nodi, boolean f)  //seeds sono id video
	{	super(n);
	Map<String,Integer> mappaIdNodi=new HashMap<String,Integer>();
	Queue<CoppiaStringhe> coda=new LinkedList<CoppiaStringhe>();//archi
	
	for(int i=0;i<nodi.size();i++)
	{	String id=nodi.get(i);
		System.out.println("Aggiungo il nodo "+i+" ("+id+")");
		mappaIdNodi.put(id,i);
		mappaNodiId.put(i, id);
	}
	}
	
	public String id(int nodo)
	{	return mappaNodiId.get(nodo);		
	}
	
	private void popolaGrafo(List<String> seeds) throws ServiceException, IOException
	{	Map<String,Integer> mappaIdNodi=new HashMap<String,Integer>();
		Queue<CoppiaStringhe> coda=new LinkedList<CoppiaStringhe>();//archi
		
		for(int i=0;i<seeds.size();i++)
		{	String id="VID::"+seeds.get(i);
			System.out.println("Aggiungo il nodo "+i+" ("+id+")");
			mappaIdNodi.put(id,i);
			mappaNodiId.put(i, id);
			List<String> correlati=extr.videoCorrelati(seeds.get(i));
			if(correlati.size()>4) ///max correlati che vengono ritornati
				correlati=correlati.subList(0, 4);
			for(String c:correlati)
				coda.offer(new CoppiaStringhe(id,"VID::"+c));
			String idUploader=extr.utente(seeds.get(i));
			coda.offer(new CoppiaStringhe(id,"USR::"+idUploader));
		}

		int nuovoNodo=seeds.size();
		while(nuovoNodo<n)
		{	CoppiaStringhe coppia=coda.poll();
			String fin=coppia.getB();
			if(!mappaIdNodi.keySet().contains(fin)) //inserire nel grafo nuovoNodo associato a fin
			{	System.out.println("Aggiungo il nodo "+nuovoNodo+" ("+fin+")");
				mappaIdNodi.put(fin,nuovoNodo);
				mappaNodiId.put(nuovoNodo, fin);
				nuovoNodo++;
				if(fin.startsWith("VID::"))
				{	List<String> correlati=extr.videoCorrelati(fin.substring(5));
					if(correlati.size()>4)
						correlati=correlati.subList(0, 4);
					for(String c:correlati)
						coda.offer(new CoppiaStringhe(fin,"VID::"+c));
					String idUploader=extr.utente(fin.substring(5));
					coda.offer(new CoppiaStringhe(fin,"USR::"+idUploader));
				}
				else
					try
					{	List<String> preferiti=extr.videoPreferiti(fin.substring(5));
						System.out.println(preferiti.size()+" preferiti di "+fin+" estratti");
						for(String p:preferiti)
							coda.offer(new CoppiaStringhe(fin,"VID::"+p));
					}
					catch(ServiceForbiddenException e)
					{	System.out.println("Preferiti di "+fin+" non estratti");
					}
			}
			else
			{	//nodo associato a fin gi� nel nel grafo
				int i=mappaIdNodi.get(coppia.getA());
				int j=mappaIdNodi.get(fin);
				System.out.println("Aggiungo un arco dal nodo "+i+" ("+mappaNodiId.get(i)+") al nodo "+j+" ("+mappaNodiId.get(j)+")");
				aggiungiArco(new Arco(i,j));
			}
		}
	}
	
	private class CoppiaStringhe
	{	String a="";
		String b="";
		
		public CoppiaStringhe(String a, String b) 
		{	this.a = a;
			this.b = b;
		}

		public String getA() {
			return a;
		}

		public void setA(String a) {
			this.a = a;
		}

		public String getB() {
			return b;
		}

		public void setB(String b) {
			this.b = b;
		}		
	}
}
